package cn.edu.jxust.controller;

import cn.edu.jxust.common.domain.entity.Account;
import cn.edu.jxust.common.domain.dto.LoginVo;
import cn.edu.jxust.core.infrastructure.util.authc.JwtToken;
import cn.edu.jxust.common.response.Result;
import cn.edu.jxust.common.response.ResultUtils;
import cn.edu.jxust.common.response.enums.ResultStatus;
import cn.edu.jxust.common.domain.web.ILoginOutController;
import cn.edu.jxust.core.domain.repository.AccountService;
import cn.edu.jxust.core.infrastructure.util.Const;
import cn.edu.jxust.core.infrastructure.util.EncryptionUtil;
import cn.edu.jxust.core.infrastructure.util.authc.JwtConst;
import cn.edu.jxust.core.infrastructure.util.authc.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;

/**
 * @author QiuKangming
 * @version 1.0
 * @description
 * @since 2020/06/29 15:23
 */
@Slf4j
@RestController
public class LoginOutController implements ILoginOutController {

    private final JwtUtils jwtUtils;
    private final AccountService accountService;

    /**
     * 自动注册Bean
     * @param jwtUtils jwtUtils
     * @param accountService accountService
     */
    @Autowired
    public LoginOutController(JwtUtils jwtUtils, AccountService accountService) {

        this.jwtUtils = jwtUtils;
        this.accountService = accountService;

    }


    @Override
    public Result AccountLogin(@RequestBody @Validated LoginVo loginVo, HttpServletResponse response){

        Account account = accountService.getByAccName(loginVo.getUsername());
        if(null == account){
//            log.error("账户不存在!");
            return ResultUtils.resultWithoutData(ResultStatus.USER_NOT_FOUND, "用户名错误");
        }
        if(Const.ACCOUNT_FORBID.equals(account.getStatus())){
//            log.error("账户已被禁用!");
            return ResultUtils.resultWithoutData(ResultStatus.USER_DISABLE, "您的账户已被禁用");
        }
        if(!account.getPassword().equals(EncryptionUtil.encrypt(loginVo.getPassword()))){
//            log.error("密码错误!");
            return ResultUtils.resultWithoutData(ResultStatus.PASSWORD_ERROR, "密码错误");
        }
        //登陆成功, 设置 token
        //生成jwt
        String jwt = jwtUtils.generateToken(account.getUsername());
        //将 token 授权信息放在登录成功返回头中
        response.setHeader(JwtConst.RESPONSE_HEADER, jwt);
        response.setHeader("Access-control-Expose-Headers", JwtConst.RESPONSE_HEADER);

        Subject subject = SecurityUtils.getSubject();
        JwtToken token = new JwtToken(jwt);
        //需要使用 Shiro 的登录认证功能才能第一次将用户信息保存在Subject中
        try{
            subject.login(token);
        }catch (Exception e){
            log.error("异常抛出, subject.login(): {}", e.getMessage());
            return ResultUtils.resultWithoutData(ResultStatus.FAILED);
        }
        return ResultUtils.resultWithData(ResultStatus.SUCCESS, "欢迎 " + account.getUsername() + " 进入空气质量监测系统", accountService.toAccountVo(account));

    }

    @Override
    public Result AccountLogout(){

        try{
            SecurityUtils.getSubject().logout();
            return ResultUtils.resultWithoutData(ResultStatus.SUCCESS);
        }catch (Exception e){
            log.error("异常抛出, subject.logout(): {}", e.getMessage());
            return ResultUtils.resultWithoutData(ResultStatus.FAILED);
        }


    }

    @Override
    public Result needLogin(){

        return ResultUtils.resultWithoutData(ResultStatus.NEED_LOGIN);

    }

    @Override
    public Result unauthc(){

        return ResultUtils.resultWithoutData(ResultStatus.NOT_AUTHC);

    }

}
